import { ref, watch, computed, nextTick, type Ref } from 'vue'
import { openFileDialog, pathToFile, pathsToFiles } from '../services/file-dialog'
import { isTauri, storageGet } from '../services/secure-storage'
import { getGroupMembers } from '../services/im-group'
import { getUser } from '../services/message'
import { useChatStore } from '../stores/chat'
import type { MentionMember } from './MentionPicker.vue'

export interface MessageInputProps {
  inputContent: string
  sending: boolean
  selectedFiles: File[]
  showEmojiPicker: boolean
  chatType?: number
  currentTargetId?: string | null
}

export interface MessageInputEmits {
  'update:inputContent': [value: string]
  'update:showEmojiPicker': [value: boolean]
  'send': []
  'enter-key': []
  'shift-enter': []
  'file-select': [file: File]
  'remove-file': [index?: number]
  'emoji-select': [emoji: string]
}

export function useMessageInput(
  props: MessageInputProps,
  emit: (event: any, ...args: any[]) => void,
  inputContentRef: Ref<any>,
  mentionPickerRef: Ref<any>
) {
  const chatStore = useChatStore()

  // Refs
  const fileInputRef = ref<HTMLInputElement | null>(null)
  const inputWrapperRef = ref<HTMLElement | null>(null)
  const showEmojiPicker = ref(props.showEmojiPicker)
  const showMentionPicker = ref(false)
  const mentionMembers = ref<MentionMember[]>([])
  const mentionSearchText = ref('')
  const mentionStartPos = ref(-1)
  const filePreviewUrls = ref<Map<File, string>>(new Map())

  // Computed
  const isGroupChat = computed(() => props.chatType === 2)

  // 获取当前用户的 open_id
  const getCurrentUserOpenId = async (): Promise<string | null> => {
    // 优先从 chatStore 获取
    if (chatStore.currentUserId) {
      return chatStore.currentUserId
    }
    
    // 从存储中获取
    if (isTauri()) {
      try {
        const openId = await storageGet('openId')
        if (openId) return openId
      } catch (e) {
        console.warn('从安全存储获取 open_id 失败:', e)
      }
    }
    
    // 从 localStorage 获取
    return localStorage.getItem('openId')
  }

  // 监听 showEmojiPicker prop 变化
  watch(() => props.showEmojiPicker, (val) => {
    showEmojiPicker.value = val
  })

  // 加载群组成员列表
  const loadGroupMembers = async () => {
    if (!isGroupChat.value || !props.currentTargetId) {
      mentionMembers.value = []
      return
    }
    
    try {
      // 获取当前用户的 open_id
      const currentUserOpenId = await getCurrentUserOpenId()
      
      const members = await getGroupMembers(props.currentTargetId, true)
      
      // 过滤掉当前用户自己
      const filteredMembers = currentUserOpenId
        ? members.filter(m => m.member_id !== currentUserOpenId)
        : members
      
      // 获取成员详细信息（名称）
      const memberDetails = await Promise.all(
        filteredMembers.map(async (m) => {
          try {
            const userInfo = await getUser(m.member_id)
            return {
              member_id: m.member_id,
              name: userInfo?.name || m.alias || m.member_id,
              alias: m.alias,
            }
          } catch (e) {
            return {
              member_id: m.member_id,
              name: m.alias || m.member_id,
              alias: m.alias,
            }
          }
        })
      )
      mentionMembers.value = memberDetails
    } catch (error) {
      console.error('加载群组成员失败:', error)
      mentionMembers.value = []
    }
  }

  // 监听聊天类型和目标ID变化，加载群组成员
  watch([() => props.chatType, () => props.currentTargetId], () => {
    if (isGroupChat.value) {
      loadGroupMembers()
    } else {
      mentionMembers.value = []
    }
  }, { immediate: true })

  // 获取光标位置
  const getCursorPosition = (): number => {
    const input = inputContentRef.value?.$el?.querySelector('textarea') as HTMLTextAreaElement
    if (input) {
      return input.selectionStart || 0
    }
    return props.inputContent.length
  }

  // 设置光标位置
  const setCursorPosition = (pos: number) => {
    nextTick(() => {
      const input = inputContentRef.value?.$el?.querySelector('textarea') as HTMLTextAreaElement
      if (input) {
        input.setSelectionRange(pos, pos)
        input.focus()
      }
    })
  }

  // 处理输入内容更新
  const handleInputUpdate = (value: string) => {
    emit('update:inputContent', value)
    
    // 检查是否输入了@符号
    if (!isGroupChat.value) {
      closeMentionPicker()
      return
    }
    
    const cursorPos = getCursorPosition()
    const textBeforeCursor = value.substring(0, cursorPos)
    
    // 查找最后一个@符号
    const lastAtIndex = textBeforeCursor.lastIndexOf('@')
    
    if (lastAtIndex >= 0) {
      // 检查@后面是否有空格或其他分隔符（表示@已经完成）
      const textAfterAt = textBeforeCursor.substring(lastAtIndex + 1)
      const hasSpaceOrNewline = /[\s\n]/.test(textAfterAt)
      
      if (!hasSpaceOrNewline) {
        // 显示成员选择器
        mentionStartPos.value = lastAtIndex
        mentionSearchText.value = textAfterAt
        showMentionPicker.value = true
        return
      }
    }
    
    // 如果没有@符号或@后面有空格，关闭选择器
    closeMentionPicker()
  }

  // 处理键盘事件
  const handleKeyDown = (event: KeyboardEvent) => {
    if (showMentionPicker.value && mentionPickerRef.value) {
      // 将键盘事件传递给成员选择器
      mentionPickerRef.value.handleKeyDown(event)
      if (['ArrowDown', 'ArrowUp', 'Enter', 'Escape'].includes(event.key)) {
        event.preventDefault()
        return
      }
    }
  }

  // 处理Enter键
  const handleEnterKey = (event?: KeyboardEvent) => {
    if (showMentionPicker.value) {
      // 如果正在选择@成员，Enter键用于确认选择
      if (mentionPickerRef.value) {
        mentionPickerRef.value.handleKeyDown(event || new KeyboardEvent('keydown', { key: 'Enter' }))
      }
      return
    }
    emit('enter-key')
  }

  // 处理成员选择
  const handleMentionSelect = (member: MentionMember) => {
    if (mentionStartPos.value < 0) {
      closeMentionPicker()
      return
    }
    
    const currentText = props.inputContent
    const textBeforeAt = currentText.substring(0, mentionStartPos.value)
    const textAfterAt = currentText.substring(mentionStartPos.value)
    
    // 找到@后面的文本结束位置（空格、换行或文本末尾）
    const match = textAfterAt.match(/^@[^\s\n]*/)
    const atTextLength = match ? match[0].length : 1
    
    // 替换@后面的文本为@用户名
    const newText = textBeforeAt + `@${member.name} ` + textAfterAt.substring(atTextLength)
    
    emit('update:inputContent', newText)
    
    // 设置光标位置到@用户名后面
    const newCursorPos = mentionStartPos.value + member.name.length + 2 // +2 for '@' and ' '
    setCursorPosition(newCursorPos)
    
    closeMentionPicker()
  }

  // 关闭成员选择器
  const closeMentionPicker = () => {
    showMentionPicker.value = false
    mentionSearchText.value = ''
    mentionStartPos.value = -1
  }

  // 点击外部关闭选择器
  const handleClickOutside = (event: MouseEvent) => {
    if (inputWrapperRef.value && !inputWrapperRef.value.contains(event.target as Node)) {
      closeMentionPicker()
    }
  }

  // 切换表情选择器
  const toggleEmojiPicker = () => {
    showEmojiPicker.value = !showEmojiPicker.value
    emit('update:showEmojiPicker', showEmojiPicker.value)
  }

  // 处理文件选择（支持多选）
  const handleFileSelect = async (event?: Event) => {
    // 如果是 Tauri 环境，使用文件对话框
    if (isTauri() && !event) {
      try {
        const result = await openFileDialog('*/*', true) // 支持多选
        if (result) {
          if (Array.isArray(result)) {
            // 多选：转换所有文件路径为 File 对象
            const files = await pathsToFiles(result)
            for (const file of files) {
              emit('file-select', file)
            }
          } else if (typeof result === 'string') {
            // 单选：转换单个文件路径为 File 对象
            const file = await pathToFile(result)
            if (file) {
              emit('file-select', file)
            }
          }
        }
      } catch (error) {
        console.error('文件选择失败:', error)
      }
      return
    }
    
    // 浏览器环境
    if (event && event.target) {
      // 如果是从 input 元素触发的事件
      const target = event.target as HTMLInputElement
      if (target && target.files && target.files.length > 0) {
        // 支持多文件选择，逐个发送
        for (let i = 0; i < target.files.length; i++) {
          const file = target.files[i]
          emit('file-select', file)
        }
        // 重置 input 值，允许选择相同文件
        target.value = ''
      }
    } else if (!event) {
      // 如果没有 event，说明是直接调用，需要触发 fileInputRef 的 click
      if (fileInputRef.value) {
        fileInputRef.value.click()
      }
    }
  }


  // 判断是否为图片文件
  const isImageFile = (file: File | null): boolean => {
    if (!file) return false
    return file.type.startsWith('image/')
  }

  // 获取图片预览 URL（为每个文件创建唯一的 URL）
  const getImagePreviewUrl = (file: File | null): string => {
    if (!file) return ''
    
    // 如果已经有这个文件的预览 URL，直接返回
    if (filePreviewUrls.value.has(file)) {
      return filePreviewUrls.value.get(file)!
    }
    
    // 创建新的预览 URL
    const url = URL.createObjectURL(file)
    filePreviewUrls.value.set(file, url)
    return url
  }

  // 清理预览 URL
  const cleanupPreviewUrls = () => {
    filePreviewUrls.value.forEach(url => {
      try {
        URL.revokeObjectURL(url)
      } catch (e) {
        console.warn('清理预览 URL 失败:', e)
      }
    })
    filePreviewUrls.value.clear()
  }

  // 监听 selectedFiles 变化，清理已删除文件的预览 URL
  watch(() => props.selectedFiles, (newFiles, oldFiles) => {
    if (oldFiles) {
      // 找出被删除的文件
      const deletedFiles = oldFiles.filter(oldFile => 
        !newFiles.some(newFile => newFile === oldFile)
      )
      
      // 清理被删除文件的预览 URL
      deletedFiles.forEach(file => {
        const url = filePreviewUrls.value.get(file)
        if (url) {
          try {
            URL.revokeObjectURL(url)
          } catch (e) {
            console.warn('清理预览 URL 失败:', e)
          }
          filePreviewUrls.value.delete(file)
        }
      })
    }
  }, { deep: true })

  // 处理图片预览错误
  const handleImagePreviewError = (event: Event) => {
    console.warn('图片预览加载失败:', event)
    // 可以在这里设置一个默认图片或隐藏预览
  }

  // 处理表情选择
  const handleEmojiSelect = (emoji: string) => {
    emit('emoji-select', emoji)
    showEmojiPicker.value = false
    emit('update:showEmojiPicker', false)
  }

  return {
    // Refs
    fileInputRef,
    inputWrapperRef,
    showEmojiPicker,
    showMentionPicker,
    mentionMembers,
    mentionSearchText,
    isGroupChat,
    // Methods
    handleInputUpdate,
    handleKeyDown,
    handleEnterKey,
    handleMentionSelect,
    closeMentionPicker,
    handleClickOutside,
    toggleEmojiPicker,
    handleFileSelect,
    isImageFile,
    getImagePreviewUrl,
    handleImagePreviewError,
    handleEmojiSelect,
    cleanupPreviewUrls,
  }
}

